home *** CD-ROM | disk | FTP | other *** search
- ;;; -*- Mode: LISP; Syntax: Common-lisp; Package: ZL-USER; Base: 10; Patch-File: T -*-
-
- ;=====================================
- (SYSTEM-INTERNALS:BEGIN-PATCH-SECTION)
- (SYSTEM-INTERNALS:PATCH-SECTION-SOURCE-FILE "SYS:l-COMPILER;OPTIMIZE.LISP.179")
- (SYSTEM-INTERNALS:PATCH-SECTION-ATTRIBUTES
- "-*- Mode: Lisp; Package: Compiler; Lowercase: T; Base: 8 -*-")
-
- ;;; Does simple constant folding. This works for everything that doesn't have
- ;;; side-effects.
- ;;; ALL operands must be constant.
- ;;; Note that commutative-constant-folder can hack this case perfectly well
- ;;; by himself for the functions he handles.
- (defun constant-fold-optimizer (form)
- (let ((eval-when-load-p nil))
- (flet ((constant-form-p (x)
- (when (constant-form-p x)
- (cond ((and (listp x)
- (eq (car x) 'quote)
- (listp (cadr x))
- (eq (caadr x) eval-at-load-time-marker))
- (setq eval-when-load-p t)
- (cdadr x))
- (t x)))))
- (if (every (cdr form) #'constant-form-p)
- (if eval-when-load-p
- (list 'quote
- (list* eval-at-load-time-marker
- (car form)
- (mapcar #'constant-form-p (cdr form))))
- (condition-case (error-object)
- (multiple-value-call #'(lambda (&rest values)
- (if (= (length values) 1)
- `',(first values)
- `(values ,@(mapcar #'(lambda (x) `',x)
- values))))
- (eval form))
- (error
- (phase-1-warning "Constant form left unoptimized: ~S~%because: ~⑨~A~⑧"
- form error-object)
- form)))
- form))))
-
-
- ;=====================================
- (SYSTEM-INTERNALS:BEGIN-PATCH-SECTION)
- (SYSTEM-INTERNALS:PATCH-SECTION-SOURCE-FILE "SYS:L-COMPILER;COMFILE.LISP.85")
- (SYSTEM-INTERNALS:PATCH-SECTION-ATTRIBUTES
- "-*- Mode: Lisp; Package: Compiler; Lowercase: T; Base: 8 -*-")
-
- ;;;
- ;;; The damn compiler doesn't compile random forms that appear at top level.
- ;;; Its difficult to do because you have to get an associated function spec
- ;;; to go with those forms. This handles that by defining a special form,
- ;;; top-level-form that compiles its body. It takes a list of eval-when
- ;;; times just like eval when does. It also takes a name which it uses
- ;;; to construct a function spec for the top-level-form function it has
- ;;; to create.
- ;;;
- ;
- ;si::
- ;(defvar *top-level-form-fdefinitions* (cl:make-hash-table :test #'equal))
- ;
- ;si::
- ;(define-function-spec-handler pcl::top-level-form
- ; (operation fspec &optional arg1 arg2)
- ; (let ((name (cadr fspec)))
- ; (selectq operation
- ; (validate-function-spec (and (= (length fspec) 2)
- ; (or (symbolp name)
- ; (listp name))))
- ; (fdefine
- ; (setf (gethash name *top-level-form-fdefinitions*) arg1))
- ; ((fdefinition fdefinedp)
- ; (gethash name *top-level-form-fdefinitions*))
- ; (fdefinition-location
- ; (ferror "It is not possible to get the fdefinition-location of ~s."
- ; fspec))
- ; (fundefine (remhash name *top-level-form-fdefinitions*))
- ; (otherwise (function-spec-default-handler operation fspec arg1 arg2)))))
- ;
- ;;;
- ;;; This is basically stolen from PROGN (surprised?)
- ;;;
- ;(si:define-special-form pcl::top-level-form (name times
- ; &body body
- ; &environment env)
- ; (declare lt:(arg-template . body) (ignore name))
- ; (si:check-eval-when-times times)
- ; (when (member 'eval times) (si:eval-body body env)))
- ;
- ;(defun (:property pcl::top-level-form lt:mapforms) (original-form form usage)
- ; (lt::mapforms-list original-form form (cddr form) 'eval usage))
-
- ;;; This is the normal function for looking at each form read from the file and calling
- ;;; *COMPILE-FORM-FUNCTION* on the sub-forms of it.
- ;;; COMPILE-TIME-TOO means override the normal cases that eval at compile time. It is
- ;;; used for recursive calls under (EVAL-WHEN (COMPILE LOAD) ...).
- ;(DEFUN COMPILE-FROM-STREAM-1 (FORM &OPTIONAL (COMPILE-TIME-TOO NIL))
- ; (CATCH-ERROR-RESTART
- ; (SYS:ERROR "Skip compiling form ~2,2\COMPILER:SHORT-S-FORMAT\" FORM)
- ; (LET ((DEFAULT-CONS-AREA (FUNCALL *COMPILE-FUNCTION* ':CONS-AREA)))
- ; (LET ((ERROR-MESSAGE-HOOK
- ; #'(LAMBDA ()
- ; (DECLARE (SYS:DOWNWARD-FUNCTION))
- ; (FORMAT T "~&While processing ~V,V\COMPILER:SHORT-S-FORMAT\"
- ; DBG:*ERROR-MESSAGE-PRINLEVEL*
- ; DBG:*ERROR-MESSAGE-PRINLENGTH*
- ; FORM))))
- ; (SETQ FORM (FUNCALL *COMPILE-FUNCTION* ':MACRO-EXPAND FORM)))
- ; (WHEN (LISTP FORM) ;Ignore atoms at top-level
- ; (LET ((FUNCTION (FIRST FORM)))
- ; (SELECTQ FUNCTION
- ; ((QUOTE)) ;and quoted constants e.g. 'COMPILE
- ; ((PROGN)
- ; (DOLIST (FORM (CDR FORM))
- ; (COMPILE-FROM-STREAM-1 FORM COMPILE-TIME-TOO)))
- ; ((EVAL-WHEN)
- ; (SI:CHECK-EVAL-WHEN-TIMES (CADR FORM))
- ; (LET ((COMPILE-P (OR (MEMQ 'COMPILE (CADR FORM))
- ; (AND COMPILE-TIME-TOO (MEMQ 'EVAL (CADR FORM)))))
- ; (LOAD-P (OR (MEMQ 'LOAD (CADR FORM)) (MEMQ 'CL:LOAD (CADR FORM))))
- ; (FORMS (CDDR FORM)))
- ; (COND (LOAD-P
- ; (DOLIST (FORM FORMS)
- ; (COMPILE-FROM-STREAM-1 FORM (AND COMPILE-P ':FORCE))))
- ; (COMPILE-P
- ; (DOLIST (FORM FORMS)
- ; (FUNCALL *COMPILE-FORM-FUNCTION* FORM ':FORCE NIL))))))
- ; ((DEFUN)
- ; (LET ((TEM (DEFUN-COMPATIBILITY (CDR FORM) :WARN-IF-OBSOLETE T)))
- ; (IF (EQ (CDR TEM) (CDR FORM))
- ; (FUNCALL *COMPILE-FORM-FUNCTION* FORM COMPILE-TIME-TOO T)
- ; (COMPILE-FROM-STREAM-1 TEM COMPILE-TIME-TOO))))
- ; ((MACRO)
- ; (FUNCALL *COMPILE-FORM-FUNCTION* FORM (OR COMPILE-TIME-TOO T) T))
- ; ((DECLARE)
- ; (DOLIST (FORM (CDR FORM))
- ; (FUNCALL *COMPILE-FORM-FUNCTION* FORM (OR COMPILE-TIME-TOO T)
- ; ;; (DECLARE (SPECIAL ... has load-time action as well.
- ; ;; All other DECLARE's do not.
- ; (MEMQ (CAR FORM) '(SPECIAL ZL:UNSPECIAL)))))
- ; ((COMPILER-LET)
- ; (COMPILER-LET-INTERNAL (CADR FORM) (CDDR FORM)
- ; #'COMPILE-FROM-STREAM-1 COMPILE-TIME-TOO))
- ; ((SI:DEFINE-SPECIAL-FORM)
- ; (FUNCALL *COMPILE-FORM-FUNCTION* FORM COMPILE-TIME-TOO T))
- ; ((MULTIPLE-DEFINITION)
- ; (DESTRUCTURING-BIND (NAME TYPE . BODY) (CDR FORM)
- ; (LET ((NAME-VALID (AND (NOT (NULL NAME))
- ; (OR (SYMBOLP NAME)
- ; (AND (LISTP NAME) (NEQ (CAR NAME) 'QUOTE)))))
- ; (TYPE-VALID (AND (NOT (NULL TYPE)) (SYMBOLP TYPE))))
- ; (UNLESS (AND NAME-VALID TYPE-VALID)
- ; (WARN "(~S ~S ~S ...) is invalid because~@
- ; ~:[~S is not valid as a definition name~;~*~]~
- ; ~:[~&~S is not valid as a definition type~;~*~]"
- ; 'MULTIPLE-DEFINITION NAME TYPE NAME-VALID NAME TYPE-VALID TYPE)))
- ; (LET* ((COMPILED-BODY NIL)
- ; (COMPILE-FUNCTION *COMPILE-FUNCTION*)
- ; (*COMPILE-FUNCTION*
- ; (LAMBDA (OPERATION &REST ARGS)
- ; (DECLARE (SYS:DOWNWARD-FUNCTION))
- ; (SELECTQ OPERATION
- ; (:DUMP-FORM
- ; (PUSH (FUNCALL COMPILE-FUNCTION :OPTIMIZE-TOP-LEVEL-FORM
- ; (FIRST ARGS))
- ; COMPILED-BODY))
- ; (:INSTALL-DEFINITION
- ; (PUSH (FORM-FOR-DEFINE *COMPILER* (FIRST ARGS) (SECOND ARGS))
- ; COMPILED-BODY))
- ; (OTHERWISE (CL:APPLY COMPILE-FUNCTION OPERATION ARGS)))))
- ; (LOCAL-DECLARATIONS `((FUNCTION-PARENT ,NAME ,TYPE)
- ; ,@LOCAL-DECLARATIONS)))
- ; (DOLIST (FORM BODY)
- ; (COMPILE-FROM-STREAM-1 FORM COMPILE-TIME-TOO))
- ; (FUNCALL COMPILE-FUNCTION :DUMP-FORM
- ; `(LOAD-MULTIPLE-DEFINITION
- ; ',NAME ',TYPE ',(NREVERSE COMPILED-BODY) NIL)))))
- ; ((pcl::top-level-form)
- ; (destructuring-bind (name times . body)
- ; (cdr form)
- ; (si:check-eval-when-times times)
- ; (let ((compile-p (or (memq 'compile times)
- ; (and compile-time-too (memq 'eval times))))
- ; (load-p (or (memq 'load times)
- ; (memq 'cl:load times)))
- ; (fspec `(pcl::top-level-form ,name)))
- ; (cond (load-p
- ; (compile-from-stream-1
- ; `(progn (defun ,fspec () . ,body)
- ; (funcall (function ,fspec)))
- ; (and compile-p ':force)))
- ; (compile-p
- ; (dolist (b body)
- ; (funcall *compile-form-function* form ':force nil)))))))
- ; (OTHERWISE
- ; (LET ((TEM (AND (SYMBOLP FUNCTION) (GET FUNCTION 'TOP-LEVEL-FORM))))
- ; (IF TEM
- ; (FUNCALL *COMPILE-FORM-FUNCTION* (FUNCALL TEM FORM) COMPILE-TIME-TOO T)
- ; (FUNCALL *COMPILE-FORM-FUNCTION* FORM COMPILE-TIME-TOO T))))))))))
- ;
- ;
-
-
- dw::
- (defun symbol-flavor-or-cl-type (symbol)
- (declare (values flavor defstruct-p deftype-fun typep-fun atomic-subtype-parent
- non-atomic-deftype))
- (multiple-value-bind (result foundp)
- (gethash symbol *flavor-or-cl-type-cache*)
- (let ((frob
- (if foundp result
- (setf (gethash symbol *flavor-or-cl-type-cache*)
- (or (get symbol 'flavor:flavor)
- (not (null (defstruct-type-p symbol)))
- (let* ((deftype (get symbol 'deftype))
- (descriptor (symbol-presentation-type-descriptor symbol))
- (typep
- (unless (and descriptor
- (presentation-type-explicit-type-function
- descriptor))
- ;; Don't override the one defined in the presentation-type.
- (get symbol 'typep)))
- (atomic-subtype-parent (find-atomic-subtype-parent symbol))
- (non-atomic-deftype
- (when (and (not descriptor) deftype)
- (not (member (first (type-arglist symbol))
- '(&rest &key &optional))))))
- (if (or typep (not (atom deftype))
- non-atomic-deftype
- ;; deftype overrides atomic-subtype-parent.
- (and (not deftype) atomic-subtype-parent))
- (list-in-area *handler-dynamic-area*
- deftype typep atomic-subtype-parent
- non-atomic-deftype)
- deftype)))))))
- (locally (declare (inline compiled-function-p))
- (etypecase frob
- (array (values frob))
- (null (values nil))
- ((member t) (values nil t))
- (compiled-function (values nil nil frob))
- (lexical-closure (values nil nil frob))
- (list (destructuring-bind (deftype typep atomic-subtype-parent non-atomic-deftype)
- frob
- (values nil nil deftype typep atomic-subtype-parent non-atomic-deftype)))
- (symbol (values nil nil nil nil frob)))))))
-
- ;;;
- ;;; The variable zwei::*sectionize-line-lookahead* controls how many lines the parser
- ;;; is willing to look ahead while trying to parse a definition. Even 2 lines is enough
- ;;; for just about all cases, but there isn't much overhead, and 10 should be enough
- ;;; to satisfy pretty much everyone... but feel free to change it.
- ;;; - MT 880921
- ;;;
-
- zwei:
- (defvar *sectionize-line-lookahead* 3)
-
- zwei:
- (DEFMETHOD (:SECTIONIZE-BUFFER MAJOR-MODE :DEFAULT)
- (FIRST-BP LAST-BP BUFFER STREAM INT-STREAM ADDED-COMPLETIONS)
- ADDED-COMPLETIONS ;ignored, obsolete
- (WHEN STREAM
- (SEND-IF-HANDLES STREAM :SET-RETURN-DIAGRAMS-AS-LINES T))
- (INCF *SECTIONIZE-BUFFER*)
- (LET ((BUFFER-TICK (OR (SEND-IF-HANDLES BUFFER :SAVE-TICK) *TICK*))
- OLD-CHANGED-SECTIONS)
- (TICK)
- ;; Flush old section nodes. Also collect the names of those that are modified, they are
- ;; the ones that will be modified again after a revert buffer.
- (DOLIST (NODE (NODE-INFERIORS BUFFER))
- (AND (> (NODE-TICK NODE) BUFFER-TICK)
- (PUSH (LIST (SECTION-NODE-FUNCTION-SPEC NODE)
- (SECTION-NODE-DEFINITION-TYPE NODE))
- OLD-CHANGED-SECTIONS))
- (FLUSH-BP (INTERVAL-FIRST-BP NODE))
- (FLUSH-BP (INTERVAL-LAST-BP NODE)))
- (DO ((LINE (BP-LINE FIRST-BP) (LINE-NEXT INT-LINE))
- (LIMIT (BP-LINE LAST-BP))
- (EOFFLG)
- (ABNORMAL T)
- (DEFINITION-LIST NIL)
- (BP (COPY-BP FIRST-BP))
- (FUNCTION-SPEC)
- (DEFINITION-TYPE)
- (STR)
- (INT-LINE)
- (first-time t)
- (future-line) ; we actually read into future line
- (future-int-line)
- (PREV-NODE-START-BP FIRST-BP)
- (PREV-NODE-DEFINITION-LINE NIL)
- (PREV-NODE-FUNCTION-SPEC NIL)
- (PREV-NODE-TYPE 'HEADER)
- (PREVIOUS-NODE NIL)
- (NODE-LIST NIL)
- (STATE (SEND SELF :INITIAL-SECTIONIZATION-STATE)))
- (NIL)
- ;; If we have a stream, read another line.
- (when (AND STREAM (NOT EOFFLG))
- (let ((lookahead (if future-line 1 *sectionize-line-lookahead*)))
- (dotimes (i lookahead) ; startup lookahead
- (MULTIPLE-VALUE (future-LINE EOFFLG)
- (LET ((DEFAULT-CONS-AREA *LINE-AREA*))
- (SEND STREAM ':LINE-IN LINE-LEADER-SIZE)))
- (IF future-LINE (SETQ future-INT-LINE (FUNCALL INT-STREAM ':LINE-OUT future-LINE)))
- (when first-time
- (setq first-time nil)
- (setq line future-line)
- (setq int-line future-int-line))
- (when eofflg
- (return)))))
-
- (SETQ INT-LINE LINE)
-
- (when int-line
- (MOVE-BP BP INT-LINE 0)) ;Record as potentially start-bp for a section
-
- ;; See if the line is the start of a defun.
- (WHEN (AND LINE
- (LET (ERR)
- (MULTIPLE-VALUE (FUNCTION-SPEC DEFINITION-TYPE STR ERR STATE)
- (SEND SELF ':SECTION-NAME INT-LINE BP STATE))
- (NOT ERR)))
- (PUSH (LIST FUNCTION-SPEC DEFINITION-TYPE) DEFINITION-LIST)
- (SECTION-COMPLETION FUNCTION-SPEC STR NIL)
- ;; List methods under both names for user ease.
- (LET ((OTHER-COMPLETION (SEND SELF ':OTHER-SECTION-NAME-COMPLETION
- FUNCTION-SPEC INT-LINE)))
- (WHEN OTHER-COMPLETION
- (SECTION-COMPLETION FUNCTION-SPEC OTHER-COMPLETION NIL)))
- (LET ((PREV-NODE-END-BP (BACKWARD-OVER-COMMENT-LINES BP ':FORM-AS-BLANK)))
- ;; Don't make a section node if it's completely empty. This avoids making
- ;; a useless Buffer Header section node. Just set all the PREV variables
- ;; so that the next definition provokes the *right thing*
- (UNLESS (BP-= PREV-NODE-END-BP PREV-NODE-START-BP)
- (SETQ PREVIOUS-NODE
- (ADD-SECTION-NODE PREV-NODE-START-BP
- (SETQ PREV-NODE-START-BP PREV-NODE-END-BP)
- PREV-NODE-FUNCTION-SPEC PREV-NODE-TYPE
- PREV-NODE-DEFINITION-LINE BUFFER PREVIOUS-NODE
- (IF (LOOP FOR (FSPEC TYPE) IN OLD-CHANGED-SECTIONS
- THEREIS (AND (EQ PREV-NODE-FUNCTION-SPEC FSPEC)
- (EQ PREV-NODE-TYPE TYPE)))
- *TICK* BUFFER-TICK)
- BUFFER-TICK))
- (PUSH PREVIOUS-NODE NODE-LIST)))
- (SETQ PREV-NODE-FUNCTION-SPEC FUNCTION-SPEC
- PREV-NODE-TYPE DEFINITION-TYPE
- PREV-NODE-DEFINITION-LINE INT-LINE))
- ;; After processing the last line, exit.
- (WHEN (OR #+ignore EOFFLG (null line) (AND (NULL STREAM) (EQ LINE LIMIT)))
- ;; If reading a stream, we should not have inserted a CR
- ;; after the eof line.
- (WHEN STREAM
- (DELETE-INTERVAL (FORWARD-CHAR LAST-BP -1 T) LAST-BP T))
- ;; The rest of the buffer is part of the last node
- (UNLESS (SEND SELF ':SECTION-NAME-TRIVIAL-P)
- ;; ---oh dear, what sort of section will this be? A non-empty HEADER
- ;; ---node. Well, ok for now.
- (PUSH (ADD-SECTION-NODE PREV-NODE-START-BP LAST-BP
- PREV-NODE-FUNCTION-SPEC PREV-NODE-TYPE
- PREV-NODE-DEFINITION-LINE BUFFER PREVIOUS-NODE
- (IF (LOOP FOR (FSPEC TYPE) IN OLD-CHANGED-SECTIONS
- THEREIS (AND (EQ PREV-NODE-FUNCTION-SPEC FSPEC)
- (EQ PREV-NODE-TYPE TYPE)))
- *TICK* BUFFER-TICK)
- BUFFER-TICK)
- NODE-LIST)
- (SETF (LINE-NODE (BP-LINE LAST-BP)) (CAR NODE-LIST)))
- (SETF (NODE-INFERIORS BUFFER) (NREVERSE NODE-LIST))
- (SETF (NAMED-BUFFER-WITH-SECTIONS-FIRST-SECTION BUFFER) (CAR (NODE-INFERIORS BUFFER)))
- (SETQ ABNORMAL NIL) ;timing windows here
- ;; Speed up completion if enabled.
- (WHEN SI:*ENABLE-AARRAY-SORTING-AFTER-LOADS*
- (SI:SORT-AARRAY *ZMACS-COMPLETION-AARRAY*))
- (SETQ *ZMACS-COMPLETION-AARRAY*
- (FOLLOW-STRUCTURE-FORWARDING *ZMACS-COMPLETION-AARRAY*))
- (RETURN
- (VALUES
- (CL:SETF (ZMACS-SECTION-LIST BUFFER)
- (NREVERSE DEFINITION-LIST))
- ABNORMAL))))))
-
-
-